package com.base.monitor.module.biz.util;

/**
 * @description 用于新增采集指标时生成采集命令
 * @author yuel
 * @date 2020年6月18日
 */
public class CRC16Util {

	/**
	 * @description 协议类型为CS是调用生成采集命令
	 * @author yuel
	 * @date 2020年8月21日
	 * @param str
	 * @return
	 */
	public static String cs(String str) {
		byte[] a = hexStringToByteArray(str);
		byte[] b = new byte[1];
		byte result;
		String res = "";
		try {
			int num = 0;
			for (int i = 0; i < a.length; i++) {
				num = (num + a[i]) % 256;
			}
			result = (byte) num;
			b[0] = result;
			res = bytesToHexString(b);
		} catch (Exception e) {
			return "0";
		}

		return res;
	}

	/**
	 * @description 根据命令获取crc16码
	 * @author yuel
	 * @date 2020年6月18日
	 * @param str
	 * @return String
	 */
	public static String crc16(String str) {
		// String res=stringToHexString(ss);
		byte[] a = hexStringToByteArray(str);
		byte[] b = getCrc16(a);
		String c = bytesToHexString(b);
		// String d=hexStringToString(c);
		return c;
	}

	/**
	 * @description 将字符串转换为16进制字符串
	 * @author yuel
	 * @date 2020年6月18日
	 * @param s
	 * @return
	 * @return String
	 */
	public static String stringToHexString(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = s.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return str;
	}

	/**
	 * @description 16进制表示的字符串转换为字节数组
	 * @author yuel
	 * @date 2020年6月18日
	 * @param s
	 * @return
	 * @return byte[]
	 */
	public static byte[] hexStringToByteArray(String s) {
		int len = s.length();
		byte[] b = new byte[len / 2];
		for (int i = 0; i < len; i += 2) {
			// 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个字节
			b[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
		}
		return b;
	}

	/**
	 * @description crc6校验
	 * @author yuel
	 * @date 2020年6月18日
	 * @param arr_buff
	 * @return
	 * @return byte[]
	 */
	public static byte[] getCrc16(byte[] arr_buff) {
		int len = arr_buff.length;
		// 预置 1 个 16 位的寄存器为十六进制FFFF, 称此寄存器为 CRC寄存器。
		int crc = 0xFFFF;
		int i, j;
		for (i = 0; i < len; i++) {
			// 把第一个 8 位二进制数据 与 16 位的 CRC寄存器的低 8 位相异或, 把结果放于 CRC寄存器
			crc = ((crc & 0xFF00) | (crc & 0x00FF) ^ (arr_buff[i] & 0xFF));
			for (j = 0; j < 8; j++) {
				// 把 CRC 寄存器的内容右移一位( 朝低位)用 0 填补最高位, 并检查右移后的移出位
				if ((crc & 0x0001) > 0) {
					// 如果移出位为 1, CRC寄存器与多项式A001进行异或
					crc = crc >> 1;
					crc = crc ^ 0xA001;
				} else
					// 如果移出位为 0,再次右移一位
					crc = crc >> 1;
			}
		}
		return intToBytes(crc);
	}

	private static byte[] intToBytes(int value) {
		byte[] src = new byte[2];
		src[1] = (byte) ((value >> 8) & 0xFF);
		src[0] = (byte) (value & 0xFF);
		return src;
	}

	/**
	 * @description byte数组转16进制字符串
	 * @author yuel
	 * @date 2020年6月18日
	 * @param bArray
	 * @return String
	 */
	public static String bytesToHexString(byte[] bArray) {
		StringBuffer sb = new StringBuffer(bArray.length);
		String sTemp;
		for (int i = 0; i < bArray.length; i++) {
			sTemp = Integer.toHexString(0xFF & bArray[i]);
			if (sTemp.length() < 2)
				sb.append(0);
			sb.append(sTemp.toUpperCase());
		}
		return sb.toString();
	}

	/**
	 * @description 16进制字符串转化为字符串
	 * @author yuel
	 * @date 2020年6月18日
	 * @param s
	 * @return String
	 * @throws Exception
	 */
	public static String hexStringToString(String s) throws Exception {
		if (s == null || s.equals("")) {
			return null;
		}
		s = s.replace(" ", "");
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {

			baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));

		}

		s = new String(baKeyword, "gbk");
		new String();

		return s;
	}

}
